package com.zheng.rpc.remoting.handler;

import com.zheng.rpc.exceptions.RpcException;
import com.zheng.rpc.factories.SingletonFactory;
import com.zheng.rpc.provider.Impl.ServiceProviderImpl;
import com.zheng.rpc.provider.ServiceProvider;
import com.zheng.rpc.remoting.dto.RpcRequest;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;

@Slf4j
public class RpcRequestHandler {
    private final ServiceProvider provider;

    public RpcRequestHandler() {
        provider = SingletonFactory.getInstance(ServiceProviderImpl.class);
    }

    public Object handle(RpcRequest rpcRequest) {
        Object service = provider.getService(rpcRequest.toRpcProperties());
        return invokeTargetMethod(rpcRequest, service);
    }

    public Object invokeTargetMethod(RpcRequest request, Object service) {
        Object result;
        try {
            Method method = service.getClass().getMethod(request.getMethodName(), request.getParamTypes());
            result = method.invoke(service, request.getParameters());
            log.info("service:[{}] successful invoke method:[{}]", request.getInterfaceName(), request.getMethodName());
        } catch (Exception e) {
            throw new RpcException(e.getMessage(), e);
        }
        return result;
    }
}
